package Flink.Partitioning_Phy;

import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class ShuffleExample {
    /*
    * 随机分区服从均匀分布（uniform distribution），所以可以把流中的数据随机打乱，
    * 均匀地传递到下游任务分区。因为是完全随机的，所以对于同样的输入数据, 每次执行得到的结果也不会相同。
    * */
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        env.setParallelism(2);

        DataStreamSource<Integer> streamSource = env.fromElements(1, 2, 3, 4, 5);

        // Todo 1、随机分区（shuffle）
        streamSource.shuffle().print();

        // Todo 2、轮询分区（Round-Robin） :轮询重分区
        /*
        * rebalance使用的是Round-Robin负载均衡算法，可以将输入流数据平均分配到下游的并行任务中去。
        * */
        streamSource.rebalance().print();

        // Todo 3、重缩放分区（rescale）
        /*
        * 调用 rescale()方法时，其实底层也是使用 RoundRobin算法进行轮询，但是只会将数据轮询发送到下游并行任务的一部分中
        * 。rescale的做法是分成小团体，发牌人只给自己团体内的所有人轮流发牌。
        * */
        streamSource.rescale().print();

        // Todo 4、广播（broadcast）
        /*
        * 这种方式其实不应该叫做“重分区”，因为经过广播之后，数据会在不同的分区都保留一份，
        * 可能进行重复处理。可以通过调用 DataStream 的 broadcast()方法，
        * 将输入数据复制并发送到下游算子的所有并行任务中去。
        * */
        streamSource.broadcast().print();

        // Todo 5、全局分区（global）
        /*
        * 将所有的输入流数据都发送到下游算子的第一个并行子任务中去。
        * 这就相当于强行让下游任务并行度变成了1，所以使用这个操作需要非常谨慎，可能对程序造成很大的压力。
        * */
        streamSource.global().print();


        env.execute();
    }
}
